package com.woniuxy.yoga.coach.service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.yoga.business.dao.model.BusinessStore;
import com.woniuxy.yoga.coach.client.BusinessStoreClient;
import com.woniuxy.yoga.coach.client.CourseClient;
import com.woniuxy.yoga.coach.client.ProductClient;
import com.woniuxy.yoga.coach.client.dto.business.BusinessStoreDTO;
import com.woniuxy.yoga.coach.client.dto.course.AloneReservationDTO;
import com.woniuxy.yoga.coach.client.dto.course.OrdinaryCourseDTO;
import com.woniuxy.yoga.coach.client.dto.product.AllTeamProductDTO;
import com.woniuxy.yoga.coach.client.dto.product.PrivateProductByIdDTO;
import com.woniuxy.yoga.coach.dao.mapper.CoachMapper;
import com.woniuxy.yoga.coach.dao.model.Coach;
import com.woniuxy.yoga.coach.model.dto.CoachDTO;
import com.woniuxy.yoga.coach.model.dto.CoachNameDTO;
import com.woniuxy.yoga.coach.model.exception.CoachException;
import com.woniuxy.yoga.coach.model.exception.CoachExceptionCode;
import com.woniuxy.yoga.coach.model.form.ModifyDeleteForm;
import com.woniuxy.yoga.coach.model.param.*;
import com.woniuxy.yoga.coach.service.service.CoachService;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.CoachState;
import com.woniuxy.yoga.commons.core.statedata.BusinessState;
import com.woniuxy.yoga.commons.core.statedata.CourseState;
import com.woniuxy.yoga.commons.core.statedata.ProductState;
import com.woniuxy.yoga.commons.core.util.IdCardUtil;
import com.woniuxy.yoga.commons.redis.util.RedisUtil;
import com.woniuxy.yoga.commons.redis.util.rediskeyutil.CoachRedisKeyUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.checkerframework.checker.units.qual.C;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 教练表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class CoachServiceImpl extends ServiceImpl<CoachMapper, Coach> implements CoachService {

    @Autowired
    private CoachMapper coachMapper;

    @Autowired
    private BusinessStoreClient businessStoreClient;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CourseClient courseClient;

    @Autowired
    private ProductClient productClient;

    /**
     * 新增教练
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addCoach(AddCoachParam param) throws Exception{
        //创建单锁
        RLock coachIdCardLock = redissonClient.getFairLock(CoachRedisKeyUtil.lockCoachByIdCard(param.getCoachIdCard()));
        RLock coachPhoneLock = redissonClient.getFairLock(CoachRedisKeyUtil.lockCoachByPhone(param.getCoachPhone()));
        //创建多资源锁
        RLock lock = redissonClient.getMultiLock(coachIdCardLock, coachPhoneLock);
        boolean isLock = lock.tryLock(10, TimeUnit.SECONDS);
        try {
            if (!isLock){
                throw new Exception("服务器繁忙请稍后再试");
            }
            //判断身份证是否合法
            boolean check = IdCardUtil.checkIdCard1(param.getCoachIdCard());
            if (check==false) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_ID_CARD_NO_LEGAL);
            //判断该身份证是否已经注册
            QueryWrapper<Coach> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("coach_id_card",param.getCoachIdCard());
            wrapper1.notIn("coach_state",CoachState.COACH_STATE_DELETE);//注销的账号排除
            //索引排序
            wrapper1.orderByAsc("coach_id");
            Coach coach1 = coachMapper.selectOne(wrapper1);
            //判断是否存在该身份证的教练
            if (coach1!=null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_ID_CARD_EXIT);
            //判断该联系方式是否已经注册
            QueryWrapper<Coach> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("coach_phone",param.getCoachPhone());
            wrapper2.notIn("coach_state",CoachState.COACH_STATE_DELETE);//注销的账号排除
            //索引排序
            wrapper2.orderByAsc("coach_id");
            Coach coach2 = coachMapper.selectOne(wrapper2);
            //判断是否存在该联系方式的教练
            if (coach2!=null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_PHONE_EXIT);
            //判断是否报错
            Result<BusinessStoreDTO> result = businessStoreClient.selByBusinessStoreId(param.getStoreId());
            if (result.getCode()!=200) throw new CoachException(result.getCode(),result.getMessage());
            BusinessStoreDTO businessStore = result.getData();
            //判断场馆是否存在
            if (businessStore==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
            //判断状态是否异常
            if (businessStore.getStoreState()== BusinessState.STORE_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
            //新增教练 对象转换
            Coach coach = BeanUtil.toBean(param, Coach.class);
            //获取年龄
            Integer coachAge = IdCardUtil.idCardToAge1(param.getCoachIdCard());
            coach.setCoachAge(coachAge);
            //获取性别
            String coachSex = IdCardUtil.idCardToGender(param.getCoachIdCard());
            coach.setCoachSex(coachSex);
            //获取状态
            coach.setCoachState(CoachState.COACH_STATE_NORMAL);
            coachMapper.insert(coach);
        }finally {
            //判断是否是自己的锁,并且还未释放
            if (coachIdCardLock.isLocked()&&coachPhoneLock.isLocked()){
                //释放锁
                lock.unlock();
            }
        }
    }

    /**
     * 判断账号是否存在
     * @param coachPhone
     * @return
     */
    @Override
    public Boolean checkPhone(String coachPhone) {
        //查询是否存在该账号
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_phone",coachPhone);
        wrapper.orderByAsc("coach_id");
        Coach coach = coachMapper.selectOne(wrapper);
        if (coach==null) return false;
        else return true;
    }

    /**
     * 密码登录
     * @param param
     * @return
     */
    @Override
    public CoachDTO passLogin(PassLoginParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_phone",param.getCoachPhone());
        wrapper.orderByAsc("coach_id");
        Coach coach = coachMapper.selectOne(wrapper);
        //判断是否存在该教练
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否异常
        if (coach.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断密码是否正确
        if (!coach.getCoachPass().equals(param.getCoachPass())) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_PASS_ERROR);
        //判断是否报错
        Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(coach.getStoreId());
        if (businessStoreResult.getCode()!=200) throw new CoachException(businessStoreResult.getCode(),businessStoreResult.getMessage());
        BusinessStoreDTO businessStore = businessStoreResult.getData();
        //判断场馆是否存在
        if (businessStore==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        //消息队列 生成登录日志
        Map<String, Object> map = new HashMap<>();
        DateTime dateTime = new DateTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String logTime = format.format(dateTime);
        map.put("logTime",logTime);
        map.put("logCoach",coach.getCoachName());
        map.put("logDesc",coach.getCoachName()+"在"+logTime+"登录该账号");
        rabbitTemplate.convertAndSend("coachLog.sendMassage",map);
        //对象转换 返回数据
        CoachDTO coachDTO = BeanUtil.toBean(coach, CoachDTO.class);
        coachDTO.setStoreName(businessStore.getStoreName());
        return coachDTO;
    }

    /**
     * 发送验证码
     * @param coachPhone
     */
    @Override
    public void sendLoginCode(String coachPhone) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_phone",coachPhone);
        wrapper.orderByAsc("coach_id");
        //判断手机号码是否存在
        Coach coach = coachMapper.selectOne(wrapper);
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断一分钟时间内是否发送了第二次验证码
        if (redisUtil.hasKey(CoachRedisKeyUtil.coachLoginCodeOneMinute(coachPhone))) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_MINUTE);
        //判断一个小时之内是否已经发送了五次
        String numbers = redisUtil.get(CoachRedisKeyUtil.coachSendNumbers(coachPhone));
        if (numbers!=null){
            if (Integer.parseInt(numbers)==5){
                throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_HOUR);
            }
        }
        //准备一个集合
        Map<String, Object> map = new HashMap<>();
        map.put("coachPhone",coachPhone);
        rabbitTemplate.convertAndSend("coachLogin.sendMassage",map);
    }

    /**
     * 验证码登录
     * @param param
     * @return
     */
    @Override
    public CoachDTO codeLogin(CodeLoginParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_phone",param.getCoachPhone());
        wrapper.orderByAsc("coach_id");
        Coach coach = coachMapper.selectOne(wrapper);
        //判断是否存在该教练
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否异常
        if (coach.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断验证码是否过期
        String code = redisUtil.get(CoachRedisKeyUtil.coachLoginCodeKey(param.getCoachPhone()));
        if (code==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_EXPIRE);
        //判断验证码是否正确
        if (!code.equals(param.getCode())) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_ERROR);
        //判断是否报错
        Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(coach.getStoreId());
        if (businessStoreResult.getCode()!=200) throw new CoachException(businessStoreResult.getCode(),businessStoreResult.getMessage());
        BusinessStoreDTO businessStore = businessStoreResult.getData();
        //判断场馆是否存在
        if (businessStore==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        //消息队列 生成登录日志
        Map<String, Object> map = new HashMap<>();
        DateTime dateTime = new DateTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String logTime = format.format(dateTime);
        map.put("logTime",logTime);
        map.put("logCoach",coach.getCoachName());
        map.put("logDesc",coach.getCoachName()+"在"+logTime+"登录该账号");
        rabbitTemplate.convertAndSend("coachLog.sendMassage",map);
        //对象转换 数据返回
        CoachDTO coachDTO = BeanUtil.toBean(coach, CoachDTO.class);
        coachDTO.setStoreName(businessStore.getStoreName());
        return coachDTO;
    }

    /**
     * 找回密码
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void findPass(FindPassParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_phone",param.getCoachPhone());
        wrapper.orderByAsc("coach_id");
        Coach coach = coachMapper.selectOne(wrapper);
        //判断教练是否存在
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否异常
        if (coach.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //修改密码
        UpdateWrapper<Coach> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("coach_pass",param.getCoachPass());
        updateWrapper.eq("coach_phone",param.getCoachPhone());
        coachMapper.update(null,updateWrapper);
    }

    /**
     * 修改密码
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyPass(ModifyPassParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("coach_id",param.getCoachId());
        Coach coach = coachMapper.selectOne(wrapper);
        //判断是否存在
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断账号是否异常
        if (coach.getCoachState()!=CoachState.COACH_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //修改密码
        UpdateWrapper<Coach> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("coach_pass",param.getCoachPass());
        updateWrapper.eq("coach_id",param.getCoachId());
        coachMapper.update(null,updateWrapper);
    }

    /**
     * 查询正常教练
     * @param param
     * @return
     */
    @Override
    public PageInfo queryStoreNormalCoach(QueryStoreNormalCoachParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        //条件搜索
        wrapper.eq("coach_state",CoachState.COACH_STATE_NORMAL);
        //门店ID搜索
        if (ObjectUtil.isNotEmpty(param.getStoreId())){
            wrapper.eq("store_id",param.getStoreId());
        }
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //教练性别搜索
        if (ObjectUtil.isNotEmpty(param.getCoachSex())){
            wrapper.eq("coach_sex",param.getCoachSex());
        }
        //索引排序查询
        wrapper.orderByAsc("coach_id");
        //分页查询
        Page<Coach> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        coachMapper.selectPage(page,wrapper);
        //集合对象转换
        List<CoachDTO> coachDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (Coach coach : page.getRecords()) {
                //对象转换
                CoachDTO coachDTO = BeanUtil.toBean(coach, CoachDTO.class);
                //商家名称赋值
                Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(coach.getStoreId());
                if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
                BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
                coachDTO.setStoreName(businessStoreDTO.getStoreName());
                //保存到集合中
                coachDTOS.add(coachDTO);
            }
        }
        //对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(coachDTOS);
        return pageInfo;
    }

    /**
     * 启用教练账号
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyNormal(ModifyNormalParam param) {
        //判断门店是否报错
        Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(param.getStoreId());
        if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        if (businessStoreDTO==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        if (businessStoreDTO.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        Coach coach = coachMapper.selectById(param.getCoachId());
        //判断是否存在教练
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否是启用
        if (coach.getCoachState()==CoachState.COACH_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断状态是否是删除
        if (coach.getCoachState()==CoachState.COACH_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断该教练是否属于该场馆
        if (coach.getStoreId()!=param.getStoreId()) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NOT_STORE);
        //修改成启用
        coach.setCoachState(CoachState.COACH_STATE_NORMAL);
        coachMapper.updateById(coach);
    }

    /**
     * 禁用教练账号
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void modifyDisable(ModifyDisableParam param) {
        Coach coach = coachMapper.selectById(param.getCoachId());
        //判断是否存在教练
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否是禁用
        if (coach.getCoachState()==CoachState.COACH_STATE_DISABLE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //判断状态是否是删除
        if (coach.getCoachState()==CoachState.COACH_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //数据转集合
        List<Integer> ids = new ArrayList<>();
        ids.add(param.getCoachId());
        if (ids.size()>0){
            //1.判断当前教练是否存在还未上完的普通课程
            Result<List<OrdinaryCourseDTO>> ordinaryResult = courseClient.getOrdinaryByCoachId(ids);
            //判断是否错误
            if (ordinaryResult.getCode()!=200) throw new CoachException(ordinaryResult.getCode(),ordinaryResult.getMessage());
            //获取数据
            List<OrdinaryCourseDTO> ordinaryCourseDTOS = ordinaryResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (ordinaryCourseDTOS!=null&&ordinaryCourseDTOS.size()>0){
                //遍历判断
                for (OrdinaryCourseDTO ordinaryCourseDTO : ordinaryCourseDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (ordinaryCourseDTO.getCourseState() == CourseState.ORDINARY_COURSE_STATE_WAIT || ordinaryCourseDTO.getCourseState() == CourseState.ORDINARY_COURSE_STATE_START){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
            //2.判断当前教练是否存在还未上完的私教预约课程
            Result<List<AloneReservationDTO>> reservationResult = courseClient.getAloneReservationByCoachId(ids);
            //判断是否错误
            if (reservationResult.getCode()!=200) throw new CoachException(reservationResult.getCode(),reservationResult.getMessage());
            //获取数据
            List<AloneReservationDTO> aloneReservationDTOS = reservationResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (aloneReservationDTOS!=null&&aloneReservationDTOS.size()>0){
                //遍历判断
                for (AloneReservationDTO aloneReservationDTO : aloneReservationDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (aloneReservationDTO.getReservationState() == CourseState.RESERVATION_STATE_CONFIRMED){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
            //3.判断当前教练是否存在还未上完的团队产品课程
            Result<List<AllTeamProductDTO>> teamProductResult = productClient.getProductByCoachId(ids);
            //判断是否错误
            if (teamProductResult.getCode()!=200) throw new CoachException(teamProductResult.getCode(),teamProductResult.getMessage());
            //获取数据
            List<AllTeamProductDTO> allTeamProductDTOS = teamProductResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (allTeamProductDTOS!=null&&allTeamProductDTOS.size()>0){
                //遍历判断
                for (AllTeamProductDTO allTeamProductDTO : allTeamProductDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (allTeamProductDTO.getTeamProductState() == ProductState.TEAM_PRODUCT_STATE_WAIT || allTeamProductDTO.getTeamProductState() == ProductState.TEAM_PRODUCT_STATE_START){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
        }
        //4.判断是否存在私教产品 存在就将该产品下架
        Result<PrivateProductByIdDTO> privateProductByIdDTOResult = productClient.checkExistPrivateByCoachId(param.getCoachId());
        if (privateProductByIdDTOResult.getCode()!=200) throw new CoachException(privateProductByIdDTOResult.getCode(),privateProductByIdDTOResult.getMessage());
        //获取数据
        PrivateProductByIdDTO privateProductByIdDTO = privateProductByIdDTOResult.getData();
        //判断是否存在
        if (privateProductByIdDTO!=null) {
            //存在私教产品 判断私教产品状态是否异常
            if (privateProductByIdDTO.getPrivateProductState()!=ProductState.PRIVATE_PRODUCT_STATE_NORMAL) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
            //将私教产品下架
            Result<?> result = productClient.disablePrivateProduct(privateProductByIdDTO.getPrivateProductId());
            if (result.getCode()!=200) throw new CoachException(result.getCode(),result.getMessage());
        }
        //判断门店是否报错
        Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(param.getStoreId());
        if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        if (businessStoreDTO==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        if (businessStoreDTO.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        //判断教练是否属于该场馆
        if (coach.getStoreId()!=param.getStoreId()) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NOT_STORE);
        //修改状态
        coach.setCoachState(CoachState.COACH_STATE_DISABLE);
        coachMapper.updateById(coach);
    }

    /**
     * 删除教练账号
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void modifyDelete(ModifyDeleteParam param) {
        Coach coach = coachMapper.selectById(param.getCoachId());
        //判断是否存在教练
        if (coach==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //判断状态是否是删除
        if (coach.getCoachState()==CoachState.COACH_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_STATE_ERROR);
        //数据转集合
        List<Integer> ids = new ArrayList<>();
        ids.add(param.getCoachId());
        if (ids.size()>0){
            //1.判断当前教练是否存在还未上完的普通课程
            Result<List<OrdinaryCourseDTO>> ordinaryResult = courseClient.getOrdinaryByCoachId(ids);
            //判断是否错误
            if (ordinaryResult.getCode()!=200) throw new CoachException(ordinaryResult.getCode(),ordinaryResult.getMessage());
            //获取数据
            List<OrdinaryCourseDTO> ordinaryCourseDTOS = ordinaryResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (ordinaryCourseDTOS!=null&&ordinaryCourseDTOS.size()>0){
                //遍历判断
                for (OrdinaryCourseDTO ordinaryCourseDTO : ordinaryCourseDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (ordinaryCourseDTO.getCourseState() == CourseState.ORDINARY_COURSE_STATE_WAIT || ordinaryCourseDTO.getCourseState() == CourseState.ORDINARY_COURSE_STATE_START){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
            //2.判断当前教练是否存在还未上完的私教预约课程
            Result<List<AloneReservationDTO>> reservationResult = courseClient.getAloneReservationByCoachId(ids);
            //判断是否错误
            if (reservationResult.getCode()!=200) throw new CoachException(reservationResult.getCode(),reservationResult.getMessage());
            //获取数据
            List<AloneReservationDTO> aloneReservationDTOS = reservationResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (aloneReservationDTOS!=null&&aloneReservationDTOS.size()>0){
                //遍历判断
                for (AloneReservationDTO aloneReservationDTO : aloneReservationDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (aloneReservationDTO.getReservationState() == CourseState.RESERVATION_STATE_CONFIRMED){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
            //3.判断当前教练是否存在还未上完的团队产品课程
            Result<List<AllTeamProductDTO>> teamProductResult = productClient.getProductByCoachId(ids);
            //判断是否错误
            if (teamProductResult.getCode()!=200) throw new CoachException(teamProductResult.getCode(),teamProductResult.getMessage());
            //获取数据
            List<AllTeamProductDTO> allTeamProductDTOS = teamProductResult.getData();
            //判断是否有课程 并且是还未完成的课程
            if (allTeamProductDTOS!=null&&allTeamProductDTOS.size()>0){
                //遍历判断
                for (AllTeamProductDTO allTeamProductDTO : allTeamProductDTOS) {
                    //判断数据状态是否存在还未上完的课程
                    if (allTeamProductDTO.getTeamProductState() == ProductState.TEAM_PRODUCT_STATE_WAIT || allTeamProductDTO.getTeamProductState() == ProductState.TEAM_PRODUCT_STATE_START){
                        throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_INCOMPLETE_COURSE);
                    }
                }
            }
        }
        //4.判断是否存在私教产品 存在就将该产品状态修改成删除
        Result<PrivateProductByIdDTO> privateProductByIdDTOResult = productClient.checkExistPrivateByCoachId(param.getCoachId());
        if (privateProductByIdDTOResult.getCode()!=200) throw new CoachException(privateProductByIdDTOResult.getCode(),privateProductByIdDTOResult.getMessage());
        //获取数据
        PrivateProductByIdDTO privateProductByIdDTO = privateProductByIdDTOResult.getData();
        //判断是否存在
        if (privateProductByIdDTO!=null) {
            //存在私教产品 判断私教产品状态是否异常
            if (privateProductByIdDTO.getPrivateProductState()==ProductState.PRIVATE_PRODUCT_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_PRIVATE_PRODUCT_STATE_ERROR);
            //将私教产品删除
            Result<?> result = productClient.deletePrivateProduct(privateProductByIdDTO.getPrivateProductId());
            if (result.getCode()!=200) throw new CoachException(result.getCode(),result.getMessage());
        }
        //判断门店是否报错
        Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(param.getStoreId());
        if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        if (businessStoreDTO==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        if (businessStoreDTO.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        //判断教练是否属于该场馆
        if (coach.getStoreId()!=businessStoreDTO.getStoreId()) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NOT_STORE);
        //修改状态
        coach.setCoachState(CoachState.COACH_STATE_DELETE);
        coachMapper.updateById(coach);
    }

    /**
     * 商家查询自己的教练
     * @param param
     * @return
     */
    @Override
    public PageInfo storeQueryAllCoach(StoreQueryNormalCoachParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        //条件搜索
        wrapper.eq("store_id",param.getStoreId());
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //教练性别搜索
        if (ObjectUtil.isNotEmpty(param.getCoachSex())){
            wrapper.eq("coach_sex",param.getCoachSex());
        }
        //教练状态搜索
        if (ObjectUtil.isNotEmpty(param.getCoachState())){
            wrapper.eq("coach_state",param.getCoachState());
        }
        //索引排序查询
        wrapper.orderByAsc("coach_id");
        //分页查询
        Page<Coach> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        coachMapper.selectPage(page,wrapper);
        //集合对象转换
        List<CoachDTO> coachDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (Coach coach : page.getRecords()) {
                //对象转换
                CoachDTO coachDTO = BeanUtil.toBean(coach, CoachDTO.class);
                //商家名称赋值
                Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(coach.getStoreId());
                if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
                BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
                coachDTO.setStoreName(businessStoreDTO.getStoreName());
                //教练状态赋值
                coachDTO.setCoachState(coach.getCoachState()==0?"正常":coach.getCoachState()==1?"禁用":"删除");
                //保存到集合中
                coachDTOS.add(coachDTO);
            }
        }
        //对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(coachDTOS);
        return pageInfo;
    }

    /**
     * 平台查询所有的教练
     * @param param
     * @return
     */
    @Override
    public PageInfo adminQueryAllCoach(AdminQueryAllCoachParam param) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        //教练姓名搜索
        if (ObjectUtil.isNotEmpty(param.getCoachName())){
            wrapper.like("coach_name",param.getCoachName());
        }
        //教练性别搜索
        if (ObjectUtil.isNotEmpty(param.getCoachSex())){
            wrapper.eq("coach_sex",param.getCoachSex());
        }
        //教练状态搜索
        if (ObjectUtil.isNotEmpty(param.getCoachState())){
            wrapper.eq("coach_state",param.getCoachState());
        }
        //场馆ID搜索
        if (ObjectUtil.isNotEmpty(param.getStoreId())){
            wrapper.eq("store_id",param.getStoreId());
        }
        //索引排序查询
        wrapper.orderByAsc("coach_id");
        //分页查询
        Page<Coach> page = new Page<>(param.getPageNum() == null ? 1 : param.getPageNum(), param.getPageSize() == null ? 5 : param.getPageSize());
        coachMapper.selectPage(page,wrapper);
        //集合对象转换
        List<CoachDTO> coachDTOS = new ArrayList<>();
        if (page.getRecords()!=null&&page.getRecords().size()>0){
            for (Coach coach : page.getRecords()) {
                //对象转换
                CoachDTO coachDTO = BeanUtil.toBean(coach, CoachDTO.class);
                //获取场馆对象信息
                Result<BusinessStoreDTO> businessStoreResult = businessStoreClient.selByBusinessStoreId(coach.getStoreId());
                //判断是否报错
                if (businessStoreResult.getCode()!=200) throw new CoachException(businessStoreResult.getCode(),businessStoreResult.getMessage());
                //获取数据
                BusinessStoreDTO businessStore = businessStoreResult.getData();
                //商家名称赋值
                coachDTO.setStoreName(businessStore.getStoreName());
                //教练状态赋值
                coachDTO.setCoachState(coach.getCoachState()==0?"正常":coach.getCoachState()==1?"禁用":"删除");
                //保存到集合中
                coachDTOS.add(coachDTO);
            }
        }
        //对象转换
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(coachDTOS);
        return pageInfo;
    }

    /**
     * 批量删除教练
     * @param storeId
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void removeCoach(Integer storeId) {
        Result<BusinessStoreDTO> businessStoreDTOResult = businessStoreClient.selByBusinessStoreId(storeId);
        //判断是否报错
        if (businessStoreDTOResult.getCode()!=200) throw new CoachException(businessStoreDTOResult.getCode(),businessStoreDTOResult.getMessage());
        //获取数据
        BusinessStoreDTO businessStoreDTO = businessStoreDTOResult.getData();
        //判断是否存在
        if (businessStoreDTO==null) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_NO_EXIT);
        //判断场馆状态是否异常
        if (businessStoreDTO.getStoreState()==BusinessState.STORE_STATE_DELETE) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_BUSINESS_STORE_STATE_ERROR);
        //通过storeId查询教练
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        wrapper.eq("store_id",storeId);
        //索引排序
        wrapper.orderByAsc("coach_id");
        List<Coach> coaches = coachMapper.selectList(wrapper);
        //判断是否存在
        if (coaches==null||coaches.size()<1) throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_COACH_NO_EXIT);
        //循环调用删除
        for (Coach coach : coaches) {
            //对象
            ModifyDeleteParam param = new ModifyDeleteParam();
            param.setCoachId(coach.getCoachId());
            param.setStoreId(storeId);
            //删除
            this.modifyDelete(param);
        }
    }

    /**
     * 商家查询正常教练的姓名
     * @param storeId
     * @return
     */
    @Override
    public List<CoachNameDTO> queryCoachName(Integer storeId) {
        QueryWrapper<Coach> wrapper = new QueryWrapper<>();
        //门店ID
        wrapper.eq("store_id",storeId);
        //正常教练
        wrapper.eq("coach_state",CoachState.COACH_STATE_NORMAL);
        //索引排序
        wrapper.orderByAsc("coach_id");
        //获取数据 返回
        List<Coach> coaches = coachMapper.selectList(wrapper);
        //集合转换
        List<CoachNameDTO> coachNameDTOS = BeanUtil.copyToList(coaches, CoachNameDTO.class);
        return coachNameDTOS;
    }
}
